Skip to content

perf(nav): reduce HTML output size ~34% by extracting repeated nav markup#3435

Merged
Mpdreamz merged 1 commit into
mainfrom
feature/trim-nav
Jun 1, 2026
Merged

perf(nav): reduce HTML output size ~34% by extracting repeated nav markup#3435
Mpdreamz merged 1 commit into
mainfrom
feature/trim-nav

Conversation

@Mpdreamz
Copy link
Copy Markdown
Member

@Mpdreamz Mpdreamz commented Jun 1, 2026

Why

The navigation tree HTML is embedded verbatim in every generated page. Because each nav item carries repeated inline strings (htmx attributes, long Tailwind utility chains, inline SVG, inline badge styles), the per-page cost multiplies across pages × nav items. At assembler scale — 69 repos, ~20k+ pages, each with its own nav tree — this was the dominant driver of the 11 GB S3 upload that takes ~6 minutes in CI.

What

htmx attribute hoistinghx-select-oob and preload were emitted on every <a> in the nav tree. htmx 2.0 inherits these from the nearest ancestor, so moving them once onto <ul id="nav-tree"> and the dropdown <ul> removes ~55 chars × nav-item-count per page.

SVG symbol reuse — The 336-char inline chevron SVG was repeated for every expandable folder. It is now defined once as a <symbol id="icon-chevron-down"> in _GlobalLayout.cshtml and each folder references it with a 40-char <svg><use href="#icon-chevron-down"/></svg>.

Named CSS component classes — Long repeated Tailwind utility strings are extracted into @layer components in styles.css: .nav-link, .nav-folder-link, .nav-folder, .nav-toggle-btn, .nav-chevron, .nav-badge, .nav-badge-{ns,cmd,alias}, .nav-subtree. The inline badge style="background:…" strings (kept inline previously to avoid Tailwind purge) are moved into authored component classes, which are never purged.

Double-space bug fix — Empty @(isTopLevel ? "font-semibold" : "") expression was producing a double space in the folder link class attribute.

How

The savings are proportional to nav tree size, not just page count — both multiply together. Measured on the local isolated build (1,472 pages, ~300 nav items):

Before After Saved
Raw HTML 558 MB 370 MB −188 MB (−34%)
Per page 379 KB 251 KB −128 KB

Projected assembler impact: ~3–4 GB off the 11 GB S3 upload, bringing CI upload time from ~6 min toward ~4 min. Larger products (more nav items per tree) see proportionally bigger savings since every optimisation is per-nav-item.

Navigation HTML is embedded verbatim in every generated page, making
per-nav-item byte cost multiply across pages × nav items. At assembler
scale (69 repos, ~20k+ pages) this dominated the S3 upload volume.

Changes:
- Hoist hx-select-oob + preload from every nav anchor onto the two
  parent <ul> elements (#nav-tree, dropdown <ul>); htmx 2.0 inherits
  them, saving ~55 chars × nav item count per page
- Replace inline SVG chevron (336 chars) with <symbol>/<use> pattern;
  symbol defined once in _GlobalLayout, each folder toggle drops to
  ~40 chars
- Extract repeated Tailwind utility strings into named CSS component
  classes: .nav-link, .nav-folder-link, .nav-folder, .nav-toggle-btn,
  .nav-chevron, .nav-badge, .nav-badge-{ns,cmd,alias}, .nav-subtree
- Remove inline badge style constants from template; move colours into
  @layer components (immune to Tailwind purge, unlike arbitrary strings)
- Fix double-space bug in folder link class from empty isTopLevel branch

Measured on local isolated build (1,472 pages):
  Before: 558 MB raw HTML  →  After: 370 MB  (−33.8%, −128 KB/page)

Projected assembler impact: ~3–4 GB off the 11 GB S3 upload.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Mpdreamz Mpdreamz requested a review from a team as a code owner June 1, 2026 13:14
@Mpdreamz Mpdreamz requested a review from cotti June 1, 2026 13:14
@Mpdreamz Mpdreamz temporarily deployed to integration-tests June 1, 2026 13:14 — with GitHub Actions Inactive
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

Warning

Review limit reached

@Mpdreamz, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 12 minutes and 50 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 2d9d0efd-acd7-41b5-b657-ca50c08007d6

📥 Commits

Reviewing files that changed from the base of the PR and between 4856b14 and 3328206.

📒 Files selected for processing (4)
  • src/Elastic.Documentation.Site/Assets/styles.css
  • src/Elastic.Documentation.Site/Navigation/_TocTree.cshtml
  • src/Elastic.Documentation.Site/Navigation/_TocTreeNav.cshtml
  • src/Elastic.Documentation.Site/_GlobalLayout.cshtml
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feature/trim-nav

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Mpdreamz Mpdreamz merged commit 13dbe91 into main Jun 1, 2026
26 checks passed
@Mpdreamz Mpdreamz deleted the feature/trim-nav branch June 1, 2026 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants